(function () {
    "use strict";

    app
        .service("AuthService", function ($q, $http, $state, $window, USER_ROLES, Oauth2, RS, DS) {
            var LOCAL_TOKEN_KEY = "_LocalTokenKey";
            var username = "";
            var isAuthenticated = false;
            var role = "";
            var authToken;
            var login_info = {
                email: '',
                isExpired: '',
                isManager: '',
                isRegistered: '',
                isMember: '',
                loginTimes: '',
                loginUpdated: '',
                mobile_Phone: '',
                realName: '',
                telephone: '',
                updated: '',
                userId: '',
                userName: '',
                validTime: '',
                basicAuthorizationData: ""
            };

            function isPrdServer() {
                if (Oauth2.server.indexOf("www.") >= 0) {
                    return true;
                }
                else {
                    return false;
                }
            }

            function loadUserCredentials() {
                var token = loadData(LOCAL_TOKEN_KEY);
                if (token) {
                    useCredentials(token);
                }
            }

            function checkUserCredentials() {
                var token = loadData(LOCAL_TOKEN_KEY);
                if (token) {
                    useCredentials(token);
                }
            }

            function storeUserCredentials(token) {
                // window.localStorage.setItem(LOCAL_TOKEN_KEY, token);
                storeData(LOCAL_TOKEN_KEY, token);
                useCredentials(token);
            }

            function isMobile() {
                var ua = navigator.userAgent;
                var app = navigator.appVersion;
                var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
                var isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
                var isAndroid = ua.match(/(Android)\s+([\d.]+)/);
                var isMobile = isIphone || isAndroid; // || true;
                return isMobile;
            }

            function storeData(key, data) {
                // if(isMobile()) {
                $window.localStorage.setItem(key, data);
                // }
                // else {
                // 	$window.sessionStorage.setItem(key, data);
                // }
            }

            function loadData(key) {
                // if(isMobile()) {
                return $window.localStorage.getItem(key);
                // }
                // else {
                // 	return $window.sessionStorage.getItem(key);
                // }
            }

            function removeData(key) {
                // if(isMobile()) {
                $window.localStorage.removeItem(key);
                // }
                // else {
                // 	$window.sessionStorage.removeItem(key);
                // }
            }

            function useCredentials(token) {
                // username = token.split(".")[0];
                isAuthenticated = true;
                authToken = token;
                // Set the token as header for your requests!
                $http.defaults.headers.common["X-Auth-Token"] = token;
            }

            function destroyUserCredentials() {
                $state.go('app.login');
                console.log('logout, destroyUserCredentials...');
                authToken = undefined;
                username = "";
                isAuthenticated = false;
                $http.defaults.headers.common["X-Auth-Token"] = undefined;
                // window.localStorage.removeItem(LOCAL_TOKEN_KEY);
                removeData(LOCAL_TOKEN_KEY);
                // window.localStorage.removeItem("_access_token");
                removeData("_access_token");
                login('demo', 'demo').then(function (res) {
                    console.log(res);
                });
            }

            function getLoginfo() {
                return login_info;
            }

            function getOpenid() {
                return login_info.openid;
            }

            var login = function (name, pwd) {
/*
                var getToken = function () {
                    return $q(function (resolve, reject) {
                        var accessurl = Oauth2.protocol + Oauth2.server + Oauth2.port + Oauth2.context + Oauth2.tokenUrl
                            + "?" + Oauth2.clientId + "&" + Oauth2.clientSecret + "&" + Oauth2.responseType + "&" + Oauth2.grantType + "&" + Oauth2.userName + name + "&"
                            + Oauth2.password + pwd;

                        var access_token = "";
                        var refresh_token = "";
                        var expires_in = "";
                        var local_time = "";

                        $http({
                            method: "GET",
                            url: accessurl
                        }).then(function successCallback(res) {
                            resolve(res);
                        }, function errorCallback(res) {
                            reject(res);
                        });
                    });
                }

                var getUserInfo = function () {
                    return $q(function (resolve, reject) {
                        console.log("AS response.data=", response.data);

                        access_token = response.data.access_token;
                        refresh_token = response.data.refresh_token;
                        expires_in = response.data.expires_in;
                        local_time = (new Date()).getTime();

                        // storeUserCredentials(access_token);

                        storeData("_access_token", access_token);
                        storeData("_refresh_token", refresh_token);
                        storeData("_expires_in", expires_in);
                        storeData("_local_time", local_time);

                        var accessurl = RS.protocol + RS.server + RS.port + RS.context + RS.markLoginUrl
                            + "?" + RS.access_token + access_token;
                        $http({
                            method: "GET",
                            url: accessurl
                        }).then(function successCallback(res) {
                            resolve(res);
                        }, function errorCallback(res) {
                            reject(res);
                        });
                    });
                };

                getToken()
                    .then(function (data) {
                        return getUserInfo(data);
                    })
                    .then(function(res){
                        console.log('ssssssssssssssssssssss', res);
                    });
*/
                return $q(function (resolve, reject) {
                    var accessurl = Oauth2.protocol + Oauth2.server + Oauth2.port + Oauth2.context + Oauth2.tokenUrl
                        + "?" + Oauth2.clientId + "&" + Oauth2.clientSecret + "&" + Oauth2.responseType + "&" + Oauth2.grantType + "&" + Oauth2.userName + name + "&"
                        + Oauth2.password + pwd;

                    var access_token = "";
                    var refresh_token = "";
                    var expires_in = "";
                    var local_time = "";

                    $http({
                        method: "GET",
                        url: accessurl
                    }).then(function successCallback(response) {
                        console.log("AS response.data=", response.data);

                        access_token = response.data.access_token;
                        refresh_token = response.data.refresh_token;
                        expires_in = response.data.expires_in;
                        local_time = (new Date()).getTime();

                        // storeUserCredentials(access_token);

                        storeData("_access_token", access_token);
                        storeData("_refresh_token", refresh_token);
                        storeData("_expires_in", expires_in);
                        storeData("_local_time", local_time);

                        accessurl = RS.protocol + RS.server + RS.port + RS.context + RS.markLoginUrl
                            + "?" + RS.access_token + access_token;
                        $http({
                            method: "GET",
                            url: accessurl
                        }).then(
                            function successCallback(response) {
                                console.log("Login success by username", response.data);

                                var data = response.data.data[0];

                                login_info.email = data.email;
                                login_info.isExpired = data.isExpired;
                                login_info.isManager = data.isManager;
                                login_info.isRegistered = data.isRegistered;
                                login_info.isMember = data.isMember;
                                login_info.loginTimes = data.loginTimes;
                                login_info.loginUpdated = data.loginUpdated;
                                login_info.mobile_Phone = data.mobile_Phone;
                                login_info.realName = data.realName;
                                login_info.telephone = data.telephone;
                                login_info.updated = data.updated;
                                login_info.userId = data.userId;
                                login_info.userName = data.userName;
                                login_info.validTime = data.validTime;

                                storeData('hhyy_hf_userInfo', angular.toJson(login_info));
                            }, function errorCallback(response) {
                                console.log("response.data=", response.data);
                            }
                        );
                        resolve(login_info);
                    }, function errorCallback(response) {
                        console.log("AS response error==========", response);
                        reject("Login Failed.");
                    });
                });
            };
            var loginUsingAccessToken = function () {
                return $q(function (resolve, reject) {
                    var access_token = loadData('_access_token') || false;
                    var expires_in = loadData('_expires_in') || 0;
                    var user = JSON.parse(loadData('hhyy_hf_userInfo')) || false;
                    var local_time = loadData('_local_time');
                    var curr_time = (new Date()).getTime();
                    var isAuthenticated = true;

                    if (curr_time - local_time >= expires_in * 1000) {
                        isAuthenticated = false;
                    }

                    if (access_token && access_token != 'undefined' && isAuthenticated == true && user.isRegistered == true) {
                        $state.go('app.rates.list');
                    } else {
                        $state.go('app.login');
                        login('demo', 'demo').then(function (res) {
                            resolve(res);
                        });
                        return;
                    }

                    var accessurl = RS.protocol + RS.server + RS.port + RS.context + RS.markLoginUrl
                        + "?" + RS.access_token + access_token;

                    $http({
                        method: "GET",
                        url: accessurl
                    }).then(function successCallback(response) {
                        if (response.data.code == 0) {
                            console.log("Login success by token", response.data);

                            var data = response.data.data[0];

                            login_info.email = data.email;
                            login_info.isExpired = data.isExpired;
                            login_info.isManager = data.isManager;
                            login_info.isRegistered = data.isRegistered;
                            login_info.isMember = data.isMember;
                            login_info.loginTimes = data.loginTimes;
                            login_info.loginUpdated = data.loginUpdated;
                            login_info.mobile_Phone = data.mobile_Phone;
                            login_info.realName = data.realName;
                            login_info.telephone = data.telephone;
                            login_info.updated = data.updated;
                            login_info.userId = data.userId;
                            login_info.userName = data.userName;
                            login_info.validTime = data.validTime;

                            storeData('hhyy_hf_userInfo', angular.toJson(login_info));

                            resolve(login_info);
                        }
                        else {
                            console.log("RS response error==========", response);
                            reject("Login Failed.");
                        }
                    }, function errorCallback(response) {
                        console.log("AS response error==========", response);
                        reject("Login Failed.");
                    });
                });
            };

            var logout = function () {
                destroyUserCredentials();
            };

            var getRsContext = function () {
                return RS.protocol + RS.server + RS.port + RS.context;
            };

            var getDsContext = function () {
                return DS.protocol + DS.server + DS.port + DS.context;
            };

            var isAuthorized = function (authorizedRoles) {
                if (!angular.isArray(authorizedRoles)) {
                    authorizedRoles = [authorizedRoles];
                }
                return (isAuthenticated && authorizedRoles.indexOf(role) !== -1);
            };

            loadUserCredentials();

            return {
                login: login,
                loginUsingAccessToken: loginUsingAccessToken,
                logout: logout,
                isAuthorized: isAuthorized,
                getOpenid: getOpenid,
                getLoginfo: getLoginfo,
                isAuthenticated: function () {
                    return isAuthenticated;
                },
                username: function () {
                    return username;
                },
                role: function () {
                    return role;
                },
                userinfo: getLoginfo,
                getRsContext: getRsContext,
                getDsContext: getDsContext,
                isPrdServer: isPrdServer,
                storeData: storeData,
                loadData: loadData,
                removeData: removeData
            };
        })

        .factory("AuthInterceptor", function ($rootScope, $q, AUTH_EVENTS) {
            return {
                responseError: function (response) {
                    $rootScope.$broadcast({
                        401: AUTH_EVENTS.notAuthenticated,
                        403: AUTH_EVENTS.notAuthorized
                    }[response.status], response);
                    return $q.reject(response);
                }
            };
        })

        .config(function ($httpProvider) {
            $httpProvider.interceptors.push("AuthInterceptor");
        })

        .controller("ViewCtrl", function ($scope, $state, $http, AuthService) {
            $scope.logout = function () {
                AuthService.logout();
                $state.go("access.login");
            };

            $scope.performValidRequest = function () {
                $http.get("http://localhost:9080/valid").then(
                    function (result) {
                        $scope.response = result;
                    });
            };

            $scope.performUnauthorizedRequest = function () {
                $http.get("http://localhost:9080/notauthorized").then(
                    function (result) {
                        // No result here..
                    }, function (err) {
                        $scope.response = err;
                    });
            };

            $scope.performInvalidRequest = function () {
                $http.get("http://localhost:9080/notauthenticated").then(
                    function (result) {
                        // No result here..
                    }, function (err) {
                        $scope.response = err;
                    });
            };
        });

})();
